<?php
class CoreCmsWidget extends CWidget {
    /**
    * Content to be displayed. Value should always be a array as it's result of findAll()
    * @var mixed
    */
    protected $content;
    
    protected $pageWidgetId;
    
    protected $pageId;
    
    protected $contentTypeId;
    private   $contentType;
    
    protected $dataSettings = null;
    
    /**
    * Properties what can be modified using widget preference screen
    * 
    * @var array
    */
    protected $properties = array();
    
    public function __construct($owner = null){
        $properties = array_keys($this->getSettingParams());
        foreach($properties as $prop)
            $this->properties[$prop] = null;

        parent::__construct($owner);
    }
    
    public function __set($name, $value) {
        if (array_key_exists($name, $this->properties))
            $this->properties[$name] = $value;
        else
            parent::__set($name, $value);
    }
    
    public function __get($name) {
        if (array_key_exists($name, $this->properties))
            return $this->properties[$name];
        
        return parent::__get($name);
    }
    
    /**
    * List of layouts can be used
    * This array, if not empty, will be converted to a Layout setting parameter
    * 
    * @var array associative array of 'LayoutFileName' => 'Layout title|description'
    */
    protected $layouts = array();
        
    public function setContent($value) {
        throw new Exception('Class '.get_class($this).' must implement function setContent($value).');
    }
    
    public function setPageWidgetId($value){
        $this->pageWidgetId = $value;
    }
    
    public function setPageId($value){
        $this->pageId = $value;
    }
    
    public function setDataSettings($value){
        $this->dataSettings = $value;
    }
    
    public function setContentTypeId($value){
        $this->contentTypeId = $value;
        $this->contentType = ContentType::model()->findByPk($this->contentTypeId);
    }
    
    public function getContentType(){
        return $this->contentType;
    }
    
    public function getContentModel(){
        if (($model = $this->getContentType()) != null)
            return $model->model;
        else
            return null;
    }
    
    public function getModuleId(){
        $class=new ReflectionClass(get_class($this));
        $path = explode(DIRECTORY_SEPARATOR, dirname($class->getFileName()));
        // it is faster to do a search from the widget's folder up to root
        $path = array_reverse($path);
        $modules = array_keys(Yii::app()->modules);
        foreach($path as $folder)
            if (array_search($folder, $modules) !== false)
                return $folder;
    }
    
    public function getData(){
        // get the content
        $model = Yii::createComponent($this->getContentModel());
        if (is_array($this->dataSettings))
            $criteria = new CDbCriteria($this->dataSettings);
        elseif(is_string($this->dataSettings))
            $criteria = new CDbCriteria(CJavaScript::jsonDecode($this->dataSettings));
        // convert parameters base on URL's querystring values
        foreach($criteria->params as $key => $value) {
            if(strpos($value, 'url:') !== false) {
                $criteria->params[$key] = Yii::app()->controller->get(substr($value,4));
            }
        }
        $content = $model->findAll($criteria);
        
        // assign content to the widget component so it can render data
        $this->setContent($content);
        
        return $content;
    }
 
    public function getCreateUrl($params = array()) {
        $className = get_class($this);
        $route = '/'.$this->getModuleId().'/widgets/'.$className.'/create';
        return url($route, $params);
    }   
    
    public function getEditUrl($params = array()){
        return $this->getPeferenceUrl($params);
    }
    
    public function getPeferenceUrl($params = array()){
        return url('/Cms/widgets/widgetBase/setting', array(
            'page_widget_id' => $this->pageWidgetId,
        ), '&', true);
    }
    
    /**
    * Derived class for a specific widget should extend this function
    * to provide preference options for user. The returned array of
    * setting parameters should match with the widget parameters defined
    * in the __widget_setting table.
    * 
    */
    public function getSettingParams() {
        $params = array(
//            'name' => array(
//                'type' => CHtml::function or Yii path to a widget. If CHtml function then the function name is in lower case
//                'rules' => array('rule name - see Yii rule classes' => array(config)),
//                'items' => array(key => value) //used for dropDownList of similar CHtml functions
//                'htmlOptions' => array()
//                // following items are used to setup the widget setting info while installing  
//                'label'           => 'Short friendly param name'
//                'value'           => 'default value'
//                'description'     => 'Full description'
//                'setting_group'   => 'General Settings'
//                'ordering'        => 0
//                'visible'         => 0
//            ),
        );
        return $params;
    }
    
    /**
    * Reset the widget_setting data in the database
    * Call this function with care as it will delete all user's default settings for the widget
    */
    public function resetSettingParams() {
        /**
        * Todo:
        * 1. base on the widget name, find out its ID
        * 2. use the getSettingParams() to obtain list of params whith default values
        * 3. with the widget id and param name, update the default value for each param in the widget_setting table
        */
    }
}